#ifndef MERGER_H_
#define MERGER_H_

#include <stdexcept>
#include <vector>
#include <fstream>
#include "../IndiceBooleano/RegistroOcurrencia.h"


class Merger {
	private:
		int _cantArchivosExistentes;
		int _ordenParticionInit;
		std::string _carpetaParticiones;
		std::string _nomArchFinal;

		std::fstream fout;
		std::vector<std::fstream*> _vecArchEntrada;

		void descargarArchivos();
		void cargarArchivos(int cantArch, int etapa);
		void fusionarArchivos(int nroFusion, int etapa);

		// Señala si todavia existen terminos a leer en las particiones
		bool existenTerminos(std::vector<RegistroOcurrencia> &terminos) const;

		// Actualiza el vector de terminos leyendo del archivo que correspode
		void leerTerminos(std::vector<RegistroOcurrencia> &terminos, RegistroOcurrencia ocurrAnterior);
		void leerTerminos(std::vector<RegistroOcurrencia> &vecOcurrencias);

		// Devuelve el menor termino del vector de ocurrencias de terminos
		RegistroOcurrencia getTerminoMinimo(std::vector<RegistroOcurrencia> &vecOcurrencias) const;

		int calcularCantEtapas(int nivelMerge, int cantTotalArchivos) const;
		std::string getNomArchivoProcesar(int orden, int etapa) const;

		// Copia el resultado a la raiz donde se encuentra el programa
		void moverArchResultado(int etapa) const;

		// Nada de copias
		Merger(const Merger&): _cantArchivosExistentes(0), _ordenParticionInit(0) { }

	public:
		Merger();
		virtual ~Merger();

		// Inicializa el mergeador de particiones
		void init(std::string carpetaParticiones, std::string nomArchFinal);

		// Fusiona "fusionesSimultaneas" cantidad de particiones a la vez
		void fusionarParticiones(int cantParticiones, int fusionesSimultaneas);
};

#endif /* MERGER_H_ */
